package com.sinosoft.web.easyui.api;

import cn.com.sinux.spring.utils.QueryHelper;
import com.sinosoft.hydra.logging.LogModules;
import com.sinosoft.hydra.um.LoginUser;
import cn.com.sinux.spring.commons.PropertyCollection;
import com.sinosoft.hydra.um.condition.SearchOrganizationCondition;
import com.sinosoft.hydra.um.condition.SearchUserCondition;
import com.sinosoft.hydra.um.constant.BaseConstant;
import com.sinosoft.hydra.um.domain.permission.SysOrganization;
import com.sinosoft.hydra.um.domain.permission.SysRole;
import com.sinosoft.hydra.um.domain.permission.SysUserMember;
import com.sinosoft.hydra.um.helper.LoggerHelper;
import com.sinosoft.hydra.um.services.*;
import cn.com.sinux.spring.utils.BeanUtils;
import cn.com.sinux.spring.utils.PageUtils;
import cn.com.sinux.spring.json.JsonFilter;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;
import java.util.List;

/**
 * @author liangminga
 * @since 0.5-alpha
 * 2014年12月17日
 * 描述：进行用户的增删查改操作。验证增加用户时用户名称重复，编辑用户时用户名称重复的功能。
 */
@Controller
@RequestMapping("api/sysMember")
public class SysMemberApi {
    /**
     * 系统用户服务类
     */
    @Autowired
    private SysUserService sysUserService;
    /**
     * 加密设置服务类
     */
    @Autowired
    private SysUserSecurityTypeService sysUserSecurityTypeService;

    @Autowired
    private SysOrganizationService sysOrganizationService;
    @Autowired
    private SysRoleService roleService;
    @Autowired
    private SysResourceService resourceService;


    /**
     * 到更新用户页面
     *
     * @param model  模型
     * @param userId 用户主键
     * @return String 页面名称
     */
    @RequestMapping("toRes")
    @RequiresPermissions("member:permission:add")
    public String toRes(Model model, @RequestParam(required = true, value = "id") String userId) {
        model.addAttribute("userId", userId);
        return "hydra_easyui/user/resource";
    }


    /**
     * 获取用户的资源
     *
     * @param userId 用户主键
     * @return String 节点集字符串
     */
    @RequestMapping(value = "showRes")
    @ResponseBody
    public Object pass(@RequestParam(required = true, value = "id") String userId) {
        return resourceService.showUserResourceAll(userId);
    }


    /**
     * 跳转到用户列表页面。
     *
     * @return String 页面名称
     */
    @RequestMapping(value = "userPage")
    @RequiresPermissions(value = "member:data:list")
    public String userPage() {
//        LoggerHelper.logInfo("访问了用户列表信息");
        return "hydra_easyui/user/index";
    }

    /**
     * 新增用户
     *
     * @param sysUserMember 用户对象
     * @return String {flag:200,msg:成功},{flag:500,msg:失败}
     */
    @RequestMapping(value = "add", method = RequestMethod.POST)
    @RequiresPermissions(value = "member:data:add")
    @ResponseBody
    public Object add(SysUserMember sysUserMember) {
        sysUserMember.setCreateTime(new Date());
        SysUserMember member = sysUserService.addSysUser(sysUserMember);
        LoggerHelper.logInfo("新增了用户{}", member.getUserNumber());
        return JsonFilter.doPropertyFilter(member, new PropertyCollection()
                .addProperties(SysUserMember.class, "id", "userNumber", "userName"));
    }

    /**
     * 修改用户
     *
     * @param sysUserMember 用户对象
     * @return String 用户对象结果:ResultJsonFormat
     */
    @RequestMapping(value = "update", method = RequestMethod.POST)
    @RequiresPermissions(value = "member:data:update")
    @ResponseBody
    public Object update(SysUserMember sysUserMember) {
        SysUserMember db = sysUserService.findOne(sysUserMember.getId());
        SysUserMember source = new SysUserMember();
        BeanUtils.copyProperties(db, source);
        SysUserMember member = sysUserService.updateSysUser(sysUserMember);
        LoggerHelper.logInfo("修改了用户{}信息{}", member.getUserName(), new LoggerHelper.PropertyMerge(source, member)
                        .addPropertyDes("userNumber", "用户名")
                        .addPropertyDes("userName", "用户姓名")
                        .addPropertyDes("userHead", "用户头像")
                        .addPropertyDes("email", "用户邮箱")
                        .addPropertyDes("mobile", "用户手机号")
                        .addPropertyDes("available", "是否启用")
                        .addPropertyDes("userPassword", "用户密码")
                        .addPropertyDes("ipAddress", "用户IP地址")
                        .addPropertyDes("orderNo", "用户序号")
        );
        return JsonFilter.doPropertyFilter(member, new PropertyCollection()
                .addProperties(SysUserMember.class, "id", "userNumber", "userName"));
    }

    @RequestMapping("updateUserInfo")
    public String toUpdateUserInfo(LoginUser loginUser) {
        return "hydra_easyui/user/updateUserInfo";
    }

    /**
     * 修改用户
     *
     * @param sysUserMember 用户对象
     * @return String 用户对象结果:ResultJsonFormat
     */
    @RequestMapping(value = "changeUserInfo", method = RequestMethod.POST)
    @RequiresPermissions(value = "member:data:update")
    @ResponseBody
    public Object changeUserInfo(SysUserMember sysUserMember, LoginUser loginUser) {
        sysUserMember.setId(loginUser.getId());
        SysUserMember db = sysUserService.findOne(sysUserMember.getId());
        SysUserMember source = new SysUserMember();
        BeanUtils.copyProperties(db, source);
        SysUserMember member = sysUserService.changeUserInfo(sysUserMember);
        LoggerHelper.logInfo("修改了自己的个人信息{}", new LoggerHelper.PropertyMerge(source, member)
                        .addPropertyDes("userNumber", "用户名")
                        .addPropertyDes("userName", "用户姓名")
                        .addPropertyDes("userHead", "用户头像")
                        .addPropertyDes("email", "用户邮箱")
                        .addPropertyDes("mobile", "用户手机号")
                        .addPropertyDes("userPassword", "用户密码")
                        .addPropertyDes("ipAddress", "用户IP地址")
        );
        return JsonFilter.doPropertyFilter(member, new PropertyCollection()
                .addProperties(SysUserMember.class, "id"));
    }

    /**
     * 到增添用户页面
     *
     * @return String 页面名称
     */
    @RequestMapping("toAdd")
    @RequiresPermissions(value = "member:data:add")
    public String toAdd() {
        return "hydra_easyui/user/addSysMember";
    }

    /**
     * 用户搜索页面
     *
     * @return 用户搜索页
     */
    @RequestMapping("toSearch")
    @RequiresPermissions(value = "member:data:list")
    public String toSearch() {
        return "hydra_easyui/user/search";
    }

    /**
     * 到更新用户页面
     *
     * @param model         模型
     * @param sysUserMember 用户对象
     * @return String 页面名称
     */
    @RequestMapping("toUpdate")
    @RequiresPermissions(value = "member:data:update")
    public String toUpdate(Model model, SysUserMember sysUserMember) {
        model.addAttribute("user", sysUserService.findOne(sysUserMember.getId()));
        return "hydra_easyui/user/updateSysMember";
    }

    /**
     * 到用户列表页面
     *
     * @return String 页面名称
     */
    @RequestMapping("toList")
    @RequiresPermissions(value = "member:data:list")
    public String toList() {
        return "hydra_easyui/user/userList";
    }

    /**
     * 取得用户列表
     *
     * @param pageNumber          页数
     * @param pageSize            页尺寸
     * @param searchUserCondition 用户名称
     * @return String JSON结果:ResultJsonFormat
     */
    @RequestMapping("conditionList")
    @ResponseBody
    public Object conditionList(
            @RequestParam(value = "page", required = false, defaultValue = "0") Integer pageNumber,
            @RequestParam(value = "rows", required = false, defaultValue = "10") Integer pageSize,
            SearchUserCondition searchUserCondition) {
        Pageable page = PageUtils.buildPageRequest(pageNumber, pageSize, "id", "available", "desc");
        Page<SysUserMember> sysUserMemberPage = sysUserService.findAllByPage(page, searchUserCondition);
        return JsonFilter.doPropertyFilter(sysUserMemberPage,
                new PropertyCollection().addProperties(SysUserMember.class, "userNumber", "id",
                        "userName", "orgsDescription", "rolesDescription", "userHead", "alias", "mobile", "email", "available"));
    }

    /**
     * 启用用户
     *
     * @param searchUserCondition 主键集合
     * @return String {flag:200,msg:成功},{flag:500,msg:失败}
     */
    @RequestMapping(value = "enable", method = RequestMethod.POST)
    @RequiresPermissions(value = "member:data:enable")
    @ResponseBody
    public Object enable(SearchUserCondition searchUserCondition) {
        List<SysUserMember> members = sysUserService.changeUserStatus(searchUserCondition.getIds(), BaseConstant.INTEGER_TRUE);
        LoggerHelper.logInfo("批量启用了用户{}", new LoggerHelper.PropertyReader<SysUserMember>(members, "userName"));
        return true;
    }

    /**
     * 角色用户树
     *
     * @param id 角色id
     * @return String 节点列表字符串
     */
    @RequestMapping("roleUsers")
    @RequiresPermissions(value = "member:role:add")
    @ResponseBody
    public Object roleUsers(@RequestParam(required = false, defaultValue = "") String id) {
        return sysUserService.roleUsers(id);
    }


    /**
     * 到更新用户页面
     *
     * @param uid   用户主键
     * @param model 模型
     * @return String 页面名称
     */
    @RequestMapping("toRole")
    @RequiresPermissions(value = "member:role:add")
    public String toRole(@RequestParam(value = "id", required = true) String uid, Model model) {
        SysUserMember userMember = sysUserService.findOne(uid);
        model.addAttribute("userMember", userMember);
        return "hydra_easyui/user/role";
    }

    /**
     * 新增用户时重复员工号验证
     *
     * @param userNumber 用户员工号
     * @return 布尔值 true:相同 false:不同
     */
    @RequestMapping("repeatValidate")
    @ResponseBody
    public Object repeatValidate(@RequestParam(value = "name", required = true) String userNumber) {
        return sysUserService.repeatValidate(userNumber, null);
    }

    /**
     * 验证用户输入密码和用户原密码是否相同
     *
     * @param oldPassword 密码
     * @return 布尔值 true:相同 false:不同
     */
    @RequestMapping("validatePasswordEqual")
    @ResponseBody
    public Object validatePasswordEqual(String oldPassword) {
        return sysUserService.validatePasswordEqual(oldPassword);
    }

    /**
     * 到更新课题组页面
     *
     * @return
     */
    @RequestMapping("toOrganization")
    @RequiresPermissions(value = "member:organization:add")
    public String toOrganization(Model model, @RequestParam(required = true, value = "id") String uid) {
        model.addAttribute("userId", uid);
        model.addAttribute("orgs", sysOrganizationService.showOrgs(uid));
        return "hydra_easyui/user/organization";
    }

    /**
     * 为用户赋予课题组
     *
     * @param searchOrganizationCondition
     * @param userId
     * @return
     */
    @RequestMapping(value = "saveUserOrganization", method = RequestMethod.POST)
    @RequiresPermissions(value = "member:organization:add")
    @ResponseBody
    public Object saveUserOrganization(SearchOrganizationCondition searchOrganizationCondition,
                                       @RequestParam(value = "userId", required = false, defaultValue = "1") String userId) {
        SysUserMember userMember = sysUserService.findOne(userId);
        List<SysOrganization> organizations = sysOrganizationService.saveUserOrganization(userId, searchOrganizationCondition.getIds(), true);
        LoggerFactory.getLogger(LogModules.TRACE_LOGGER).info("对用户{}分配了课题组{}", userMember.getUserName(),
                new LoggerHelper.PropertyReader<SysOrganization>(organizations, "orgName"));
        return JsonFilter.doPropertyFilter(organizations, new PropertyCollection()
                .addProperties(SysOrganization.class, "id"));
    }

    /**
     * 为用户赋予角色
     *
     * @param searchUserCondition 资源id集合 JsonList(eg:{"resourceIds":["1","2","3"]})
     * @return 操作结果
     */
    @RequestMapping(value = "saveUserRole", method = RequestMethod.POST)
    @RequiresPermissions(value = "member:role:add")
    @ResponseBody
    public Object saveUserRole(
            SearchUserCondition searchUserCondition) {
        SysUserMember userMember = sysUserService.findOne(searchUserCondition.getId());
        List<SysRole> roles = roleService.saveUserRole(searchUserCondition.getRoleIds(), searchUserCondition.getId());
        LoggerFactory.getLogger(LogModules.TRACE_LOGGER).info("修改用户{}的角色{}", userMember.getUserName(),
                new LoggerHelper.PropertyReader<SysRole>(roles, "roleName"));
        return JsonFilter.doPropertyFilter(roles,
                new PropertyCollection().addProperties(SysRole.class, "id"));
    }

    /**
     * 展示课题组下的员工
     *
     * @param orgId 课题组编号
     * @return 返回用户结果
     */
    @RequestMapping("showUserOfOrg")
    @ResponseBody
    public Object showUserOfOrg(@RequestParam(value = "orgId", required = true) String orgId) {
        List<SysUserMember> list = sysUserService.queryUserOfOrganization(orgId);
        return JsonFilter.doPropertyFilter(list,
                new PropertyCollection().addProperties(SysUserMember.class, "id", "userName"));
    }

    /**
     * 展示课题组下的员工
     *
     * @param orgId 课题组编号
     * @return 返回用户结果
     */
    @RequestMapping("showOrgUsers")
    @ResponseBody
    public Object showOrgUsers(@RequestParam(value = "orgId", required = false) String orgId) {
        SearchUserCondition condition = new SearchUserCondition();
        condition.setAvailable(BaseConstant.INTEGER_TRUE);
        condition.setOrgId(orgId);
        List<SysUserMember> list = sysUserService.findAll(condition);
        return JsonFilter.doPropertyFilter(list,
                new PropertyCollection().addProperties(SysUserMember.class, "id", "userName"));
    }

    /**
     * 查询所有可用用户list
     *
     * @param searchUserCondition
     * @return
     */
    @RequestMapping("list")
    @ResponseBody
    public Object list(SearchUserCondition searchUserCondition) {
        searchUserCondition.setAvailable(BaseConstant.INTEGER_TRUE);
        List<SysUserMember> list = sysUserService.findAll(searchUserCondition);
        return JsonFilter.doPropertyFilter(list, new PropertyCollection()
                .addProperties(SysUserMember.class, "id", "userName", "userNumber", "userDescription"));
    }

    /**
     * 查询所有可用用户list(除了自己)
     *
     * @param searchUserCondition
     * @return
     */
    @RequestMapping("listButMe")
    @ResponseBody
    public Object listButMe(SearchUserCondition searchUserCondition, final LoginUser loginUser) {
        searchUserCondition.setAvailable(BaseConstant.INTEGER_TRUE);
        List<SysUserMember> list = sysUserService.findAll(searchUserCondition);
        list = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<SysUserMember>() {

            public boolean match(SysUserMember sysUserMember) {
                return sysUserMember.getId() != loginUser.getId();
            }
        });
        return JsonFilter.doPropertyFilter(list, new PropertyCollection()
                .addProperties(SysUserMember.class, "id", "userName", "userNumber", "userDescription"));
    }

    /**
     * 取得用户列表(除了自己)
     *
     * @param pageNumber          页数
     * @param pageSize            页尺寸
     * @param searchUserCondition 用户名称
     * @return String JSON结果:ResultJsonFormat
     */
    @RequestMapping("allUserButMe")
    @ResponseBody
    public Object allUserButMe(
            @RequestParam(value = "page", required = false, defaultValue = "0") Integer pageNumber,
            @RequestParam(value = "rows", required = false, defaultValue = "10") Integer pageSize,
            SearchUserCondition searchUserCondition, final LoginUser loginUser) {
        Pageable pageable = PageUtils.buildPageRequest(pageNumber, pageSize, "id", "desc");
        searchUserCondition.setAvailable(1);
        searchUserCondition.setButMe(true);
        Page<SysUserMember> page = sysUserService.findAllByPage(pageable, searchUserCondition);
        return JsonFilter.doPropertyFilter(page,
                new PropertyCollection().addProperties(SysUserMember.class, "userNumber", "id",
                        "userName", "orgsDescription"));
    }

    /**
     * 取得可用用户列表
     *
     * @param pageNumber          页数
     * @param pageSize            页尺寸
     * @param searchUserCondition 用户名称
     * @return String JSON结果:ResultJsonFormat
     */
    @RequestMapping("allUsers")
    @ResponseBody
    public Object allUsers(
            @RequestParam(value = "page", required = false, defaultValue = "0") Integer pageNumber,
            @RequestParam(value = "rows", required = false, defaultValue = "10") Integer pageSize,
            SearchUserCondition searchUserCondition, final LoginUser loginUser) {
        Pageable pageable = PageUtils.buildPageRequest(pageNumber, pageSize, "id", "desc");
        searchUserCondition.setAvailable(1);
        Page<SysUserMember> page = sysUserService.findAllByPage(pageable, searchUserCondition);
        return JsonFilter.doPropertyFilter(page,
                new PropertyCollection().addProperties(SysUserMember.class, "userNumber", "id",
                        "userName", "orgsDescription"));
    }
    /**
     * 页面跳转
     *
     * @return 跳转制定也
     */
    @RequestMapping("choose")
//    @RequiresPermissions("ebom:data:add")
    public String choose(Model model, SearchUserCondition searchUserCondition) {
        model.addAttribute("condition", searchUserCondition);
        return "hydra_easyui/user/choose";
    }

    /**
     * 批量删除考勤登记
     * @param condition
     * @return
     */
    @RequestMapping(value = "delete")
    @RequiresPermissions(value = "member:data:delete")
    @ResponseBody
    public Object delete(SearchUserCondition condition){
        List<SysUserMember> members = sysUserService.delUsers(condition.getIds());
        LoggerHelper.logInfo("删除了用户{}", new LoggerHelper.PropertyReader<SysUserMember>(members, "userName"));
        return true;
    }
}
